package com.hd.trans.utils;

import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.hd.trans.R;
import com.hd.trans.framework.rom.HuaweiUtils;
import com.hd.trans.framework.rom.MeizuUtils;
import com.hd.trans.framework.rom.MiuiUtils;
import com.hd.trans.framework.rom.OppoUtils;
import com.hd.trans.framework.rom.PermissionFragment;
import com.hd.trans.framework.rom.PermissionListener;
import com.hd.trans.framework.rom.QikuUtils;
import com.hd.trans.framework.rom.RomUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

public class PermissionUtil {

    private static final String TAG = "PermissionsUtil";

    private PermissionFragment fragment;

    /**
     *
     * @param fragmentManager activity中传getSupportFragmentManager();Fragment中传getChildFragmentManager()
     * @return
     */
    public PermissionUtil(@NonNull FragmentManager fragmentManager) {
        fragment = getPermissionsFragment(fragmentManager);
    }

    private PermissionFragment getPermissionsFragment(FragmentManager fragmentManager) {
        PermissionFragment fragment = (PermissionFragment) fragmentManager.findFragmentByTag(TAG);
        boolean isNewInstance = fragment == null;
        if (isNewInstance) {
            fragment = new PermissionFragment();
            fragmentManager
                    .beginTransaction()
                    .add(fragment, TAG)
                    .commit();
            fragmentManager.executePendingTransactions();
        }

        return fragment;
    }

    /**
     * 外部调用申请权限
     * @param permissions 申请的权限
     * @param listener 监听权限接口
     */
    public void requestMultiPermissions(int requestCode, String[] permissions, PermissionListener listener) {

        if (Build.VERSION.SDK_INT < 23){
            listener.onGranted(requestCode);
            return;
        }

        fragment.setListener(listener);
        fragment.requestMultiPermissions(requestCode,permissions);

    }


    public void checkIsHavePermission(Activity activity, String[] permissions, PermissionCallback callback){
        if (checkIsHavePermission(activity, permissions)) {
            callback.doNext();
        } else {
            showPermissionDialogPreposition(activity, permissions, 9988, new PermissionListener() {
                @Override
                public void onGranted(int requestCode) {
                    callback.doNext();
                }

                @Override
                public void onDenied(int requestCode, List<String> deniedPermission) {

                }

                @Override
                public void onShouldShowRationale(boolean isFirst, int requestCode, List<String> deniedPermission) {
                    // 将String[]转换为ArrayList
                    List<String> permissionList = new ArrayList<>(Arrays.asList(permissions));
                    //permissions 包含Manifest.permission.MANAGE_EXTERNAL_STORAGE
                    //如果包含Manifest.permission.MANAGE_EXTERNAL_STORAGE，就跳转到管理外部存储的设置页面
                    if (permissionList.contains(Manifest.permission.MANAGE_EXTERNAL_STORAGE)){
                        toManagerExternalStorageSettings(activity);
                    }
                    //如果不是第一次申请权限，就跳转到系统权限设置页面
                    else if (!isFirst){
                        toPermissionSettingSystemWay(activity);
                    }
                }
            });
        }
    }


    public boolean checkIsHavePermission(Activity activity, String permission){
        if (Manifest.permission.SYSTEM_ALERT_WINDOW.equals(permission)
                || Settings.ACTION_MANAGE_OVERLAY_PERMISSION.equals(permission)){
            return haveFloatPermission(activity);
        }
        int perm = activity.checkCallingOrSelfPermission(permission);
        return perm == PackageManager.PERMISSION_GRANTED;
    }

    public boolean checkIsHavePermission(Activity activity, String[] permissions){
        for (int i = 0 ; i < permissions.length ; i++){
            if (Manifest.permission.SYSTEM_ALERT_WINDOW.equals(permissions[i])
                    || Settings.ACTION_MANAGE_OVERLAY_PERMISSION.equals(permissions[i])){
                if(!haveFloatPermission(activity)){
                    return false;
                }
            }else if (Manifest.permission.MANAGE_EXTERNAL_STORAGE.equals(permissions[i])){
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    if(!Environment.isExternalStorageManager()){
                        return false;
                    }
                }
            }else {
                int perm = activity.checkCallingOrSelfPermission(permissions[i]);
                if (perm == PackageManager.PERMISSION_DENIED){
                    return false;
                }
            }

        }
        return true;
    }

    public ArrayList<String> CheckPermisionWhichHave(FragmentActivity activity, String[] Permissions){
        ArrayList<String> permissionWhichHave = new ArrayList<>();
        for (int i = 0 ; i < Permissions.length ; i++){
            int perm = activity.checkCallingOrSelfPermission(Permissions[i]);
            if (perm == PackageManager.PERMISSION_GRANTED){
                permissionWhichHave.add(Permissions[i]);
            }
        }
        return permissionWhichHave;
    }

    public ArrayList<String> CheckPermisionWhichNotHave(Context context, String[] Permissions){
        ArrayList<String> permissionWhichNotHave = new ArrayList<>();
        for (int i = 0 ; i < Permissions.length ; i++){
            int perm = context.checkCallingOrSelfPermission(Permissions[i]);
            if (perm != PackageManager.PERMISSION_GRANTED){
                permissionWhichNotHave.add(Permissions[i]);
            }
        }
        return permissionWhichNotHave;
    }

    /**
     * 外部调用申请权限
     * @param permission 申请的权限
     * @param listener 监听权限接口
     */
    public void requestOnePermission(int requestCode, String permission, PermissionListener listener) {
        if (Build.VERSION.SDK_INT < 23){
            listener.onGranted(requestCode);
            return;
        }

        fragment.setListener(listener);
        fragment.requestOnePermission(requestCode,permission);

    }


    public static void toManagerExternalStorageSettings(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            Uri uri = Uri.fromParts("package", context.getPackageName(), null);
            intent.setData(uri);
            context.startActivity(intent);
        }
    }

    /**
     * 打开应用的系统权限设置页面,用的系统的隐式intent打开set界面
     *
     * @param context
     */
    public static void toPermissionSettingSystemWay(Context context) {
        if (context!=null){
            final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.fromParts("package", context.getPackageName(), null));
            if (intent.resolveActivity(context.getPackageManager()) != null) {
                context.startActivity(intent);
            }
        }

    }
    /**
     * 跳转到权限设置界面，网上的代码，说是适配了各大手机厂商的ROM，但是发现个别手机提示App会悬浮到其他App上。
     *
     * @param context
     */
    public static void toPermissionSettingAdaptROMWay(Context context) throws NoSuchFieldException, IllegalAccessException {
        if (Build.VERSION.SDK_INT < 23) {
            if (RomUtils.checkIsMiuiRom()) {
                MiuiUtils.applyMiuiPermission(context);
            } else if (RomUtils.checkIsMeizuRom()) {
                MeizuUtils.applyPermission(context);
            } else if (RomUtils.checkIsHuaweiRom()) {
                HuaweiUtils.applyPermission(context);
            } else if (RomUtils.checkIs360Rom()) {
                QikuUtils.applyPermission(context);
            } else if (RomUtils.checkIsOppoRom()) {
                OppoUtils.applyOppoPermission(context);
            } else {
                RomUtils.getAppDetailSettingIntent(context);
            }
        } else {
            if (RomUtils.checkIsMeizuRom()) {
                MeizuUtils.applyPermission(context);
            } else {
                if (RomUtils.checkIsOppoRom() || RomUtils.checkIsVivoRom()
                        || RomUtils.checkIsHuaweiRom() || RomUtils.checkIsSamsunRom()) {
                    RomUtils.getAppDetailSettingIntent(context);
                } else if (RomUtils.checkIsMiuiRom()) {
                    MiuiUtils.toPermisstionSetting(context);
                } else {
                    RomUtils.commonROMPermissionApplyInternal(context);
                }
            }
        }
    }

    public void showPermissionDialogPreposition(Context context, final String[] permission, int code, final PermissionListener permissionListener) {

        final Dialog myDialog = new Dialog(context, R.style.BottomDialogStyle);
        View view = LayoutInflater.from(context).inflate(R.layout.permission_tip_layout, (ViewGroup) null);
        LinearLayout xiangji = view.findViewById(R.id.xiangji);
        LinearLayout maikefeng = view.findViewById(R.id.maikefeng);
        LinearLayout cunchu = view.findViewById(R.id.cunchu);
        LinearLayout floatWindow = view.findViewById(R.id.float_window);
        ArrayList<String> permissionWhichNotHave = CheckPermisionWhichNotHave(context, permission);

        for (String item : permissionWhichNotHave) {

            if (item.equals(Manifest.permission.RECORD_AUDIO)) {
                maikefeng.setVisibility(View.VISIBLE);
            } else if (item.equals(Manifest.permission.CAMERA)) {
                xiangji.setVisibility(View.VISIBLE);
            } else if (item.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    || item.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)){
                cunchu.setVisibility(View.VISIBLE);
            } else if (item.equals(Manifest.permission.SYSTEM_ALERT_WINDOW)
                    || item.equals(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)){
                floatWindow.setVisibility(View.VISIBLE);
            }
        }


        TextView sure = (TextView) view.findViewById(R.id.retry);
        ImageView close = (ImageView) view.findViewById(R.id.close);
        sure.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                myDialog.dismiss();
                requestMultiPermissions(code, permission, permissionListener);
            }
        });
        close.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                myDialog.dismiss();
            }
        });

        myDialog.setContentView(view);
        myDialog.show();
        Window window = myDialog.getWindow();
        window.setGravity(Gravity.BOTTOM);
        WindowManager.LayoutParams lp = window.getAttributes();
        Resources var10001 = Resources.getSystem();
        lp.width = (int) (var10001.getDisplayMetrics().widthPixels * 0.9);
        Window var10000 = myDialog.getWindow();
        var10000.setAttributes(lp);
    }

    private static boolean haveFloatPermission(Context context){
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
            return true;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            try {
                Class<?> cls = Class.forName("android.content.Context");
                Field declaredField = cls.getDeclaredField("APP_OPS_SERVICE");
                declaredField.setAccessible(true);
                Object obj = declaredField.get(cls);
                if (!(obj instanceof String)) {
                    return false;
                }
                String str2 = (String) obj;
                obj = cls.getMethod("getSystemService", String.class).invoke(context, str2);
                cls = Class.forName("android.app.AppOpsManager");
                Field declaredField2 = cls.getDeclaredField("MODE_ALLOWED");
                declaredField2.setAccessible(true);
                Method checkOp = cls.getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class);
                int result = (Integer) checkOp.invoke(obj, 24, Binder.getCallingUid(), context.getPackageName());
                return result == declaredField2.getInt(cls);
            } catch (Exception e) {
                return false;
            }
        } else {
            return Settings.canDrawOverlays(context);
        }
    }
}